package gray.boolber.vk.web.api.manager;

import gray.boolber.vk.web.api.account.RuntimePreferences;
import gray.boolber.vk.web.api.account.VKSession;
import gray.boolber.vk.web.api.callbacks.VKActionListener;
import gray.boolber.vk.web.api.callbacks.VKDialogListener;
import gray.boolber.vk.web.api.dialogs.VKDialog;
import gray.boolber.vk.web.api.utils.APIConstants;
import gray.boolber.vk.web.api.utils.ApiParser;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Message;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public enum VKManager implements VKDialogListener{
	INSTANCE;
	private Context context;
    private VKDialogListener _listener;
	private WebView mWebView;
	private VKActionListener callback;

	public void init(Context context){
        this.context = context;
        NewsFeedManager.INSTANCE.init();
    }
    
    public void setListener(VKDialogListener listener){
    	_listener = listener; 
    }
    public void loginVK(VKActionListener callback){
    	this.callback=callback;
		runHidedWebView();
    }
    
    
    public void showLoginDialog(){
        new VKDialog(context,APIConstants.OAUTH_AUTHORIZE_URL_FULLACCESS,this).show();        
    }
            
    //parse vkontakte JSON response
    private boolean parseResponse(String jsonStr){
        boolean errorFlag = true;
        
        JSONObject jsonObj = null;
        try {
           jsonObj = new JSONObject(jsonStr);
           JSONObject errorObj = null;
           
           if( jsonObj.has("error") ) {
               errorObj = jsonObj.getJSONObject("error");
               int errCode = errorObj.getInt("error_code");
               if( errCode == 14){
                   errorFlag = false;
               }
           }
           if(jsonObj.has("response")){
        	   JSONObject respObj = jsonObj.getJSONObject("response");
               int respCode = errorObj.getInt("post_id");
           }
           
        }
        catch (JSONException e) {
            e.printStackTrace();
        }
        
        return errorFlag;       
    }
            
            //publicate message to vk users' wall 
    public boolean postToWall(String message, VKActionListener callback) {
    	boolean errorFlag = true;
    
        String[] params = RuntimePreferences.from(context).getVKSessionToken();
        
        String accessToken = params[0];
        String ownerId = params[2];
        
        //set request uri params
        String actionURL=APIConstants.VK_POST_TO_WALL_URL + "owner_id="+ownerId+"&message="+Uri.encode(message)+"&access_token="+accessToken;
        
        //send request to vkontakte api
        HttpClient client = new DefaultHttpClient();
	    HttpGet request = new HttpGet(actionURL);
	    
	    try {
	        HttpResponse response = client.execute(request);
	        HttpEntity entity = response.getEntity();
	
	        String responseText = EntityUtils.toString(entity);
	        
	        //parse response for error code or not
	        errorFlag = parseResponse(responseText);
	        callback.onSuccess(errorFlag);
	        //Log.d(Constants.DEBUG_TAG,"response text="+responseText);
	    }
	    catch(ClientProtocolException cexc){
	            cexc.printStackTrace();
	    }
	    catch(IOException ioex){
	            ioex.printStackTrace();
	    }
	    
	    return errorFlag;
    }
    public boolean getNewsFeed(String _from,VKActionListener callback){
    	boolean errorFlag=true;
    	
    	String[] params = RuntimePreferences.from(context).getVKSessionToken();
        
        String accessToken = params[0];
        String ownerId = params[2];
        
        //set request uri params
        String actionURL=APIConstants.VK_GET_NEWS_FEED_URL 
        		//+"&start_time="+System.currentTimeMillis()
        		+"&from="+(_from.length()>0?_from:"")
        		+"&count="+50
        		+"&access_token="+accessToken;
        
        //send request to vkontakte api
        HttpClient client = new DefaultHttpClient();
	    HttpGet request = new HttpGet(actionURL);
	    
	    try {
	        HttpResponse response = client.execute(request);
	        HttpEntity entity = response.getEntity();
	
	        String responseText = EntityUtils.toString(entity);
	        
	        //parse response for error code or not
	        //errorFlag = parseResponse(responseText);
	        ApiParser.parseNewsFeedResponse(responseText);
	        if(callback!=null) callback.onSuccess(errorFlag);
	        //Log.d(Constants.DEBUG_TAG,"response text="+responseText);
	    }
	    catch(ClientProtocolException cexc){
	            cexc.printStackTrace();
	    }
	    catch(IOException ioex){
	            ioex.printStackTrace();
	    }
    	return errorFlag;
    }
    public boolean isAccessTokenValid(){
    	String[] params = RuntimePreferences.from(context).getVKSessionToken();
        String accessToken = params[0];
        String ownerId = params[2];
        
        //set request uri params
        String actionURL=APIConstants.VK_GET_FRIENDS_ONLINE_URL+"access_token="+accessToken;
        HttpClient client = new DefaultHttpClient();
	    HttpGet request = new HttpGet(actionURL);
	    
	    try {
	        HttpResponse response = client.execute(request);
	        HttpEntity entity = response.getEntity();
	
	        String responseText = EntityUtils.toString(entity);
	        if(responseText.contains("error") ) {
	        	JSONObject jo=(new JSONObject(responseText)).getJSONObject("error");
	        	int eCode=Integer.parseInt(jo.getString("error_code"));
	        	if(eCode==5){
	        		return false;
	        	}
	        }
	    }
	    catch(ClientProtocolException cexc){
	            cexc.printStackTrace();
	    }
	    catch(IOException ioex){
	            ioex.printStackTrace();
	    } catch (JSONException e) {
			e.printStackTrace();
		}
	    return true;
    }
    public String[] getAccessToken(String url) {
        String[] query = url.split("#");
        String[] params = query[1].split("&");
        for(int i=0;i<params.length;i++){
        	params[i]=params[i].substring(params[i].indexOf("=")+1);
        }
        //params[0] - access token=value, params[1] - expires_in=value, 
        //params[2] - user_id=value
        return params;
    }
            
    public boolean hasAccessToken() {
        String[] params =  RuntimePreferences.from(context).getVKSessionToken();
        if( params != null ) {
            long accessTime = Long.parseLong(params[3]); 
            long currentTime = System.currentTimeMillis();
            long expireTime = (currentTime - accessTime) / 1000;
            
            //Log.d(Constants.DEBUG_TAG,"expires time="+expireTime);
            
            if( params[0].equals("") & params[1].equals("") & params[2].equals("") & Long.parseLong(params[3]) ==0 ){
                //Log.d(Constants.DEBUG_TAG,"access token empty");  
                return false;
            }
            else if( expireTime >= Long.parseLong(params[1]) ) {
            	//Log.d(Constants.DEBUG_TAG,"access token time expires out");
                return false;
            }
            else {
                //Log.d(Constants.DEBUG_TAG,"access token ok");
                return true;
            }
        }
        return false;
    }
    

	@Override
	public void onComplete(String url) {
		RuntimePreferences.from(context).saveVKAccessToken(getAccessToken(url));
		if(callback!=null){
			callback.onSuccess(true);
		}
		
	}


	@Override
	public void onError(String description) {
		// TODO Auto-generated method stub
		
	}
//000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
//-------------------------login vk methods-------------------------------------------------------------------------------------
//000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
	public void runHidedWebView() {
	    mWebView = new WebView(context);
	    mWebView.setWebViewClient(new VkWebViewClient());
	    mWebView.getSettings().setJavaScriptEnabled(true);
	    mWebView.loadUrl(APIConstants.OAUTH_AUTHORIZE_URL);
	}
	
	private class VkWebViewClient extends WebViewClient { 
	    @Override
	    public boolean shouldOverrideUrlLoading(WebView view, String url) {
	        if (url.startsWith(APIConstants.CALLBACK_URL) & ( !url.contains("error") )) {
                //Log.d(Constants.DEBUG_TAG,"url contains callback url");
                return true;
	        } 
	        else if(url.contains("error")){
                return false;
	        }
	        else {
                //Log.d(Constants.DEBUG_TAG,"url not contains callback url");
	            view.loadUrl(url);
                return true;
	        }
	    }
	    
	    @Override
	    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
	        super.onReceivedError(view, errorCode, description, failingUrl);
	    }
	    
	    @Override
	    public void onPageStarted(WebView view, String url, Bitmap favicon) {
	        super.onPageStarted(view, url, favicon);
	        
	        if(url.contains("error") ) {
	            return;
	        }
	        else if( url.contains("access_token")) {
	        	RuntimePreferences.from(context).saveVKAccessToken(getAccessToken(url));
	        	callback.onSuccess(true);
	            return;
	        }
	       // mSpinner.show();
	    }
	}
    
   
}
